import React from 'react'
import { clsx } from 'clsx'

export interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'outline' | 'danger' | 'ghost'
  size?: 'sm' | 'md' | 'lg'
  loading?: boolean
  icon?: React.ReactNode
  iconPosition?: 'left' | 'right'
  fullWidth?: boolean
  as?: React.ElementType
  children?: React.ReactNode
  className?: string
  disabled?: boolean
  onClick?: React.MouseEventHandler<HTMLElement>
  type?: 'button' | 'submit' | 'reset'
  [key: string]: any // Allow any additional props for polymorphic component
}

const Button = React.forwardRef<any, ButtonProps>(
  (
    {
      className,
      variant = 'primary',
      size = 'md',
      loading = false,
      icon,
      iconPosition = 'left',
      fullWidth = false,
      disabled,
      children,
      as: Component = 'button',
      ...props
    },
    ref
  ) => {
    // Type assertions for object access
    const currentVariant = variant as keyof typeof variantClasses
    const currentSize = size as keyof typeof sizeClasses
    const currentIconSize = size as keyof typeof iconSizeClasses
    const baseClasses = [
      'inline-flex items-center justify-center font-medium rounded-md',
      'focus:outline-none focus:ring-2 focus:ring-offset-2',
      'transition-colors duration-200',
      'disabled:opacity-50 disabled:cursor-not-allowed'
    ]

    const variantClasses = {
      primary: [
        'bg-primary-600 text-white',
        'hover:bg-primary-700 focus:ring-primary-500',
        'disabled:hover:bg-primary-600'
      ],
      secondary: [
        'bg-gray-600 text-white',
        'hover:bg-gray-700 focus:ring-gray-500',
        'disabled:hover:bg-gray-600'
      ],
      outline: [
        'border border-gray-300 text-gray-700 bg-white',
        'hover:bg-gray-50 focus:ring-primary-500',
        'disabled:hover:bg-white'
      ],
      danger: [
        'bg-red-600 text-white',
        'hover:bg-red-700 focus:ring-red-500',
        'disabled:hover:bg-red-600'
      ],
      ghost: [
        'text-gray-700 bg-transparent',
        'hover:bg-gray-100 focus:ring-gray-500',
        'disabled:hover:bg-transparent'
      ]
    }

    const sizeClasses = {
      sm: 'px-3 py-1.5 text-sm',
      md: 'px-4 py-2 text-sm',
      lg: 'px-6 py-3 text-base'
    }

    const iconSizeClasses = {
      sm: 'h-4 w-4',
      md: 'h-5 w-5',
      lg: 'h-6 w-6'
    }

    const LoadingSpinner = () => (
      <svg
        className={clsx('animate-spin', iconSizeClasses[currentIconSize])}
        xmlns="http://www.w3.org/2000/svg"
        fill="none"
        viewBox="0 0 24 24"
      >
        <circle
          className="opacity-25"
          cx="12"
          cy="12"
          r="10"
          stroke="currentColor"
          strokeWidth="4"
        />
        <path
          className="opacity-75"
          fill="currentColor"
          d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
        />
      </svg>
    )

    const renderIcon = () => {
      if (loading) return <LoadingSpinner />
      if (icon) {
        return React.cloneElement(icon as React.ReactElement, {
          className: clsx(iconSizeClasses[currentIconSize], (icon as any).props?.className)
        })
      }
      return null
    }

    return (
      <Component
        ref={ref}
        className={clsx(
          baseClasses,
          variantClasses[currentVariant],
          sizeClasses[currentSize],
          fullWidth && 'w-full',
          className
        )}
        disabled={disabled || loading}
        {...props}
      >
        {iconPosition === 'left' && renderIcon() && (
          <span className={clsx(children && 'mr-2')}>{renderIcon()}</span>
        )}
        {children}
        {iconPosition === 'right' && renderIcon() && (
          <span className={clsx(children && 'ml-2')}>{renderIcon()}</span>
        )}
      </Component>
    )
  }
)

Button.displayName = 'Button'

export { Button }
